package com.housekeeping.controller.api;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.housekeeping.model.Category;
import com.housekeeping.model.HousekeepingService;
import com.housekeeping.model.User;
import com.housekeeping.service.HousekeepingServiceService;
import com.housekeeping.service.impl.HousekeepingServiceServiceImpl;
import com.housekeeping.utils.ApiResponse;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
/**
 * 家政服务管理模块控制器
 */
@WebServlet("/api/services/*")
public class ServiceApiController extends HttpServlet {
    
    private HousekeepingServiceService serviceService = new HousekeepingServiceServiceImpl();
    private ObjectMapper objectMapper = new ObjectMapper();
    
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) 
            throws ServletException, IOException {
        
        String pathInfo = req.getPathInfo();
        
        try {
            if (pathInfo == null || pathInfo.equals("/")) {
                handleGetAllServices(req, resp);
            } else if (pathInfo.equals("/search")) {
                handleSearchServices(req, resp);
            } else if (pathInfo.matches("/\\d+")) {
                handleGetServiceById(req, resp);
            } else if (pathInfo.equals("/categories")) {
                handleGetCategories(req, resp);
            } else if (pathInfo.equals("/available")) {
                handleGetAvailableServices(req, resp);
            } else {
                ApiResponse.sendJsonResponse(req, resp, ApiResponse.error(404, "Not Found"));
            }
        } catch (Exception e) {
            e.printStackTrace();
            ApiResponse.sendJsonResponse(req, resp, ApiResponse.error(500, "Internal Error"));
        }
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) 
            throws ServletException, IOException {
        
        try {
            handleCreateService(req, resp);
        } catch (Exception e) {
            e.printStackTrace();
            ApiResponse.sendJsonResponse(req, resp, ApiResponse.error(500, "Internal Error"));
        }
    }

    @Override
    protected void doPut(HttpServletRequest req, HttpServletResponse resp) 
            throws ServletException, IOException {
        
        String pathInfo = req.getPathInfo();
        
        try {
            if (pathInfo != null && pathInfo.matches("/\\d+/status")) {
                handleUpdateServiceStatus(req, resp);
            } else if (pathInfo != null && pathInfo.matches("/\\d+")) {
                handleUpdateService(req, resp);
            } else {
                ApiResponse.sendJsonResponse(req, resp, ApiResponse.error(404, "Not Found"));
            }
        } catch (Exception e) {
            e.printStackTrace();
            ApiResponse.sendJsonResponse(req, resp, ApiResponse.error(500, "Internal Error"));
        }
    }

    @Override
    protected void doDelete(HttpServletRequest req, HttpServletResponse resp) 
            throws ServletException, IOException {
        
        String pathInfo = req.getPathInfo();
        
        try {
            if (pathInfo != null && pathInfo.matches("/\\d+")) {
                handleDeleteService(req, resp);
            } else {
                ApiResponse.sendJsonResponse(req, resp, ApiResponse.error(404, "Not Found"));
            }
        } catch (Exception e) {
            e.printStackTrace();
            ApiResponse.sendJsonResponse(req, resp, ApiResponse.error(500, "Internal Error"));
        }
    }
    
    private void handleGetAllServices(HttpServletRequest req, HttpServletResponse resp) 
            throws IOException {
        
        String categoryParam = req.getParameter("categoryId");
        List<HousekeepingService> services;
        
        if (categoryParam != null) {
            int categoryId = Integer.parseInt(categoryParam);
            services = serviceService.getServicesByCategory(categoryId);
        } else {
            services = serviceService.getAllServices();
        }
        
        ApiResponse.sendJsonResponse(req, resp, ApiResponse.success(services));
    }
    
    private void handleGetServiceById(HttpServletRequest req, HttpServletResponse resp) 
            throws IOException {
        
        String pathInfo = req.getPathInfo();
        int serviceId = Integer.parseInt(pathInfo.substring(1));
        
        HousekeepingService service = serviceService.getServiceById(serviceId);
        if (service != null) {
            ApiResponse.sendJsonResponse(req, resp, ApiResponse.success(service));
        } else {
            ApiResponse.sendJsonResponse(req, resp, ApiResponse.error(404, "Service not found"));
        }
    }
    
    private void handleGetCategories(HttpServletRequest req, HttpServletResponse resp) 
            throws IOException {
        
        List<Category> categories = serviceService.getAllCategories();
        ApiResponse.sendJsonResponse(req, resp, ApiResponse.success(categories));
    }
    
    private void handleGetAvailableServices(HttpServletRequest req, HttpServletResponse resp) 
            throws IOException {
        
        List<HousekeepingService> services = serviceService.getAvailableServices();
        ApiResponse.sendJsonResponse(req, resp, ApiResponse.success(services));
    }

    private void handleSearchServices(HttpServletRequest req, HttpServletResponse resp) 
            throws IOException {
        
        String keyword = req.getParameter("keyword");
        if (keyword == null || keyword.trim().isEmpty()) {
            handleGetAllServices(req, resp);
            return;
        }
        
        List<HousekeepingService> services = serviceService.searchServices(keyword);
        ApiResponse.sendJsonResponse(req, resp, ApiResponse.success(services));
    }

    private void handleCreateService(HttpServletRequest req, HttpServletResponse resp) 
            throws IOException {
        
        HttpSession session = req.getSession(false);
        if (session == null) {
            ApiResponse.sendJsonResponse(req, resp, ApiResponse.error(401, "Not logged in"));
            return;
        }
        
        User currentUser = (User) session.getAttribute("user");
        if (currentUser == null || currentUser.getUserType() != 1) {
            ApiResponse.sendJsonResponse(req, resp, ApiResponse.error(403, "Permission denied"));
            return;
        }
        
        try {
            String requestBody = req.getReader().lines()
                .reduce("", (accumulator, actual) -> accumulator + actual);
            
            Map<String, Object> serviceData = objectMapper.readValue(
                requestBody, new TypeReference<Map<String, Object>>() {});
            
            HousekeepingService service = new HousekeepingService();
            service.setServiceName((String) serviceData.get("serviceName"));
            service.setCategoryId((Integer) serviceData.get("categoryId"));
            service.setPrice(new BigDecimal(((Number) serviceData.get("price")).doubleValue()));
            service.setUnit((String) serviceData.get("unit"));
            service.setServiceTime((String) serviceData.get("serviceTime"));
            service.setDescription((String) serviceData.get("description"));
            service.setStatus(1); // 默认可用状态
            
            if (serviceService.addService(service)) {
                ApiResponse.sendJsonResponse(req, resp, ApiResponse.success("Service created successfully"));
            } else {
                ApiResponse.sendJsonResponse(req, resp, ApiResponse.error(400, "Failed to create service"));
            }
        } catch (Exception e) {
            e.printStackTrace();
            ApiResponse.sendJsonResponse(req, resp, ApiResponse.error(400, "Invalid request data"));
        }
    }

    private void handleUpdateService(HttpServletRequest req, HttpServletResponse resp) 
            throws IOException {
        
        String pathInfo = req.getPathInfo();
        int serviceId = Integer.parseInt(pathInfo.substring(1));
        
        HttpSession session = req.getSession(false);
        if (session == null) {
            ApiResponse.sendJsonResponse(req, resp, ApiResponse.error(401, "Not logged in"));
            return;
        }
        
        User currentUser = (User) session.getAttribute("user");
        if (currentUser == null || currentUser.getUserType() != 1) {
            ApiResponse.sendJsonResponse(req, resp, ApiResponse.error(403, "Permission denied"));
            return;
        }
        
        try {
            String requestBody = req.getReader().lines()
                .reduce("", (accumulator, actual) -> accumulator + actual);
            
            Map<String, Object> serviceData = objectMapper.readValue(
                requestBody, new TypeReference<Map<String, Object>>() {});
            
            HousekeepingService service = serviceService.getServiceById(serviceId);
            if (service == null) {
                ApiResponse.sendJsonResponse(req, resp, ApiResponse.error(404, "Service not found"));
                return;
            }
            
            // 更新服务信息
            if (serviceData.get("serviceName") != null) {
                service.setServiceName((String) serviceData.get("serviceName"));
            }
            if (serviceData.get("categoryId") != null) {
                service.setCategoryId((Integer) serviceData.get("categoryId"));
            }
            if (serviceData.get("price") != null) {
                service.setPrice(new BigDecimal(((Number) serviceData.get("price")).doubleValue()));
            }
            if (serviceData.get("unit") != null) {
                service.setUnit((String) serviceData.get("unit"));
            }
            if (serviceData.get("serviceTime") != null) {
                service.setServiceTime((String) serviceData.get("serviceTime"));
            }
            if (serviceData.get("description") != null) {
                service.setDescription((String) serviceData.get("description"));
            }
            
            if (serviceService.updateService(service)) {
                ApiResponse.sendJsonResponse(req, resp, ApiResponse.success("Service updated successfully"));
            } else {
                ApiResponse.sendJsonResponse(req, resp, ApiResponse.error(400, "Failed to update service"));
            }
        } catch (Exception e) {
            e.printStackTrace();
            ApiResponse.sendJsonResponse(req, resp, ApiResponse.error(400, "Invalid request data"));
        }
    }

    private void handleUpdateServiceStatus(HttpServletRequest req, HttpServletResponse resp) 
            throws IOException {
        
        String pathInfo = req.getPathInfo();
        int serviceId = Integer.parseInt(pathInfo.substring(1, pathInfo.indexOf("/status")));
        
        HttpSession session = req.getSession(false);
        if (session == null) {
            ApiResponse.sendJsonResponse(req, resp, ApiResponse.error(401, "Not logged in"));
            return;
        }
        
        User currentUser = (User) session.getAttribute("user");
        if (currentUser == null || currentUser.getUserType() != 1) {
            ApiResponse.sendJsonResponse(req, resp, ApiResponse.error(403, "Permission denied"));
            return;
        }
        
        try {
            String requestBody = req.getReader().lines()
                .reduce("", (accumulator, actual) -> accumulator + actual);
            
            Map<String, Object> statusData = objectMapper.readValue(
                requestBody, new TypeReference<Map<String, Object>>() {});
            
            HousekeepingService service = serviceService.getServiceById(serviceId);
            if (service == null) {
                ApiResponse.sendJsonResponse(req, resp, ApiResponse.error(404, "Service not found"));
                return;
            }
            
            Integer status = (Integer) statusData.get("status");
            if (status == null) {
                ApiResponse.sendJsonResponse(req, resp, ApiResponse.error(400, "Status is required"));
                return;
            }
            
            service.setStatus(status);
            if (serviceService.updateService(service)) {
                ApiResponse.sendJsonResponse(req, resp, ApiResponse.success("Service status updated successfully"));
            } else {
                ApiResponse.sendJsonResponse(req, resp, ApiResponse.error(400, "Failed to update service status"));
            }
        } catch (Exception e) {
            e.printStackTrace();
            ApiResponse.sendJsonResponse(req, resp, ApiResponse.error(400, "Invalid request data"));
        }
    }

    private void handleDeleteService(HttpServletRequest req, HttpServletResponse resp) 
            throws IOException {
        
        String pathInfo = req.getPathInfo();
        int serviceId = Integer.parseInt(pathInfo.substring(1));
        
        HttpSession session = req.getSession(false);
        if (session == null) {
            ApiResponse.sendJsonResponse(req, resp, ApiResponse.error(401, "Not logged in"));
            return;
        }
        
        User currentUser = (User) session.getAttribute("user");
        if (currentUser == null || currentUser.getUserType() != 1) {
            ApiResponse.sendJsonResponse(req, resp, ApiResponse.error(403, "Permission denied"));
            return;
        }
        
        HousekeepingService service = serviceService.getServiceById(serviceId);
        if (service == null) {
            ApiResponse.sendJsonResponse(req, resp, ApiResponse.error(404, "Service not found"));
            return;
        }
        
        if (serviceService.deleteService(serviceId)) {
            ApiResponse.sendJsonResponse(req, resp, ApiResponse.success("Service deleted successfully"));
        } else {
            ApiResponse.sendJsonResponse(req, resp, ApiResponse.error(400, "Failed to delete service"));
        }
    }
} 